﻿using System;
using System.Collections.Generic;
using Corona.TagContract;
using Corona.TagServer.Exception;

namespace Corona.TagServer
{
    /// <summary>
    /// 为了方便服务器端进行查询，将Corona.TagToolkit.Query在此重新声明，并做了相应的修改
    /// 可能触发InvalidQueryException
    /// </summary>
    public class Query
    {
        private Dictionary<Tag, Pair<long, long>> tagWeightPair;
        public Dictionary<Tag, Pair<long, long>> TagWeightPair
        {
            get { return tagWeightPair; }
        }

        private double relevance = 1;
        public double Relevance
        {
            get { return relevance; }
        }

        private long totalScore = 0;
        public long TotalScore
        {
            get { return totalScore; }
        }

        private double targetScore = 0;
        public double TargetScore
        {
            get { return targetScore; }
        }

        /// <summary>
        /// 该构造方法接收一个字符串作为参数，一般来说是由Corona.TagToolkit.Query.ToString()给出的字符串
        /// </summary>
        /// <param name="queryString">合法的查询字串</param>
        public Query(string queryString)
        {
            string[] querys = queryString.Split(',');
            tagWeightPair = new Dictionary<Tag, Pair<long, long>>();
            foreach (string query in querys)
            {
                string[] temp = query.Split(new char[] { '*', ':' });
                if (temp.Length == 0) continue;
                if (temp.Length == 4)
                {
                    try
                    {
                        Pair<long,long> weightPair=new Pair<long,long>(Int32.Parse(temp[1]),Int32.Parse(temp[3]));
                        //不关心的域权重为0，相应的域便被设置为"*"，方便进行SQL查询
                        if (weightPair.A == 0) temp[0] = "*";
                        if (weightPair.B == 0) temp[2] = "*";
                        totalScore += weightPair.B;
                        tagWeightPair.Add(new Tag(temp[0], temp[2]), weightPair);
                    }
                    catch (System.FormatException e)
                    {
                        throw new InvalidQueryException("不合法的查询：不合法的权值");
                    }
                }
                else if (temp.Length == 1)
                {
                    try
                    {
                        //是相关度
                        relevance = Double.Parse(temp[0]);
                        if (relevance > 1) relevance = 1;
                        else if (relevance < 0) relevance = 0;
                    }
                    catch (System.FormatException e)
                    {
                        throw new InvalidQueryException("不合法的查询：不合法的相关度");
                    }
                }
                else
                {
                    throw new InvalidQueryException("不合法的查询：查询语句格式有误");
                }
            }
            targetScore = totalScore * relevance;
        }
    }

    /// <summary>
    /// 为了便于构造SQL查询语句而添加的类，在其中对字符串和通配符进行了处理
    /// </summary>
    public class QueryTag : Tag
    {
        /// <summary>
        /// 为了便于构造统一的SQL语句，又因为SQL语句中要求字符串用''扩起来、对于通配符的处理比较特殊，特写了此构造函数
        /// </summary>
        /// <param name="tag">未经处理的Tag，如果类型信息为空，应该设置为*</param>
        public QueryTag(Tag tag)
        {
            if (tag.Name.Equals("*")) this.Name = " like '%'";
            else this.Name = "='" + tag.Name + "'";
            if (tag.Value.Equals("*")) this.Value = " like '%'";
            else this.Value = "='" + tag.Value + "'";
        }
    }
}
